package com.auth.Sercurity.controller;

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;

/**
 * @author： hj
 * @version： 1.0
 * @fileDes：  流程控制器
 * @date： 2022/3/27 22:37
 */

//@Controller
//@RequestMapping("/redict")
@RestController
public class RedictContrller {
    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  单个流程部署
     * @date： 2022/3/27 22:36
     */
//    @RequestMapping("/hello")
    @GetMapping("/singleDeployment")
    public String singleDeployment(){

//        创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        使用RepositoryService进行部署
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("bpmn/Leave.bpmn")
                .name("员工请假审批流程")
                .deploy();
//        输出部署信息
        System.out.println(deployment.getId());
        System.out.println(deployment.getName());
        return "部署成功";
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  流程打包部署 zip压缩方式
     * @date： 2022/3/27 22:36
     */
    @GetMapping("/zipDeployment")
    public String zipDeployment(){
//        定义一个Zip输入流
        InputStream inputStream = this.getClass()
                .getClassLoader()
                .getResourceAsStream("bpmn/Leave.zip");
        try {
            if (inputStream==null){
                throw new NoSuchFieldException("没有找到文件");
            }
            ZipInputStream zipInputStream = new ZipInputStream(inputStream);
//        获取一个repositotyService
            ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
            Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();
            System.out.println(deployment.getId()+"======"+deployment.getName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return "部署成功";
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  启动定义
     * @date： 2022/3/27 22:34
     */
    @GetMapping("/startProcess")
    public String startProcess(){
//    创建ProcessEngine
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
//        获取runtimeService
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
//        根据流程定义的Id启动流程
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myLeave","busnissKey");
//        输出内容
        System.out.println("流程定义Id :"+instance.getProcessDefinitionId());
        System.out.println("流程实例Id :"+instance.getId());
        System.out.println("当前活动Id :"+instance.getActivityId());
        return "启动成功";
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  发起流程
     * @date： 2022/3/27 22:35
     */
    @GetMapping("/workCommitProcess")
    public String workCommitProcess(String roleName){
//
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
//        创建一个taskService
        TaskService taskService = defaultProcessEngine.getTaskService();
//        根据流程key 和任务负责人 查询任务
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("myLeave")
                .taskAssignee(roleName)
                .list();
        for (Task task : taskList) {
            System.out.println("流程实例Id :"+task.getProcessInstanceId());
            System.out.println("任务Id :"+task.getId());
            System.out.println("任务负责人 :"+task.getAssignee());
            System.out.println("任务名称 :"+task.getName());
        }
        return taskList.toString();
    }


    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  完成任务
     * @date： 2022/3/27 22:35
     */
    @GetMapping("/completTask")
    public String completTask(String roleName){
        //    获取ProcessEngines
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
//    获取taskService
        TaskService taskService = defaultProcessEngine.getTaskService();
//    根据流程key  和任务的负责人 查询任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myLeave")
                .taskAssignee(roleName)
                .singleResult();
//    完成任务 参数：任务Id
        taskService.complete(task.getId());
        return task.getAssignee()+"完成"+task.getId()+"=="+task.getName()+"任务";
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  查询流程定义
     * @date： 2022/3/27 22:35
     */
    @GetMapping("/queryprocessDefinition")
    public String queryprocessDefinition(){
//    获取引擎
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
//    repositoryService
        RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
//    查询当前定义的所有的流程

        List<ProcessDefinition> definitionList = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("myLeave")
                .orderByProcessDefinitionVersion()
                .desc()
                .list();

        for (ProcessDefinition processDefinition : definitionList) {
            System.out.println("流程定义ID:"+processDefinition.getId());
            System.out.println("流程定义名 :"+processDefinition.getName());
            System.out.println("流程定义Key:"+processDefinition.getKey());
            System.out.println("流程版本号:"+processDefinition.getVersion());
            System.out.println("流程部署Id:"+processDefinition.getDeploymentId());
        }
        return definitionList.toString();
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  查看流程执行情况
     * @date： 2022/3/27 22:35
     */
    @GetMapping("/queryProcessInstance")
    public String queryProcessInstance(){
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        List<ProcessInstance> myLeave = runtimeService.createProcessInstanceQuery()
                .processDefinitionKey("myLeave")
                .list();
        for (ProcessInstance instance : myLeave) {
            System.out.println("流程实例 ID:"+instance.getProcessInstanceId());
            System.out.println("所属流程定义Id :"+instance.getProcessDefinitionId());
            System.out.println("是否执行完成:"+instance.isEnded());
            System.out.println("是否暂停:"+instance.isSuspended());
            System.out.println("当前活动标识:"+instance.getActivityId());
            System.out.println("业务关键字:"+instance.getBusinessKey());
        }
        return myLeave.toString();
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  删除定义的流程
     * @date： 2022/3/30 21:21
     */
    @GetMapping("/delete")
    public void deleteProcess(){
//        获取部署流程的Id
        String deploymentId="";
//        获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        得到RepositoryService
        RepositoryService service = processEngine.getRepositoryService();
//        删除流程定义,如果该流程定义已有流程实例启动则删除失败
        service.deleteDeployment(deploymentId);
//        ture  级联删除流程定义，如果该流程定义有流程启动也可以删除，默认FALSE
//        service.deleteDeployment(deploymentId,true);
    }


//    /**
//     * @author： hj
//     * @version： 1.0
//     * @methodDes：  到处流程定义图片和BPMN文件
//     * @date： 2022/3/30 22:10
//     */
//    @GetMapping("/getProcess")
//    public void getProcess(String processKey){
////        定义流程名称可以
//
////        获得引擎
//        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
////        获取RepositoryService
//        RepositoryService engineRepositoryService = processEngine.getRepositoryService();
////        得到查询器,得到流程定义
//        ProcessDefinition processDefinition = engineRepositoryService.createProcessDefinitionQuery().processDefinitionKey(processKey).singleResult();
////        根据流程定义信息得到部署Id
//        String deploymentId = processDefinition.getDeploymentId();
////        通过RepositoryService的方法，实现读取图片和PBMN信息
////        图片流
//        InputStream picInputStieam = engineRepositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
////        BPMN 流
//        InputStream bpmnInputStream = engineRepositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
////        构造outPutStream流
//        try {
//            File file_pic = new File("C:\\Users\\Administrator\\Desktop\\pic.png");
//            File file_bpmn=new File("C:\\Users\\Administrator\\Desktop\\bmp.bpmn");
//            FileOutputStream pic_stream=new FileOutputStream(file_pic);
//            FileOutputStream bpmn_stream=new FileOutputStream(file_bpmn);
//            IOUtils.copy(picInputStieam,pic_stream);
//            IOUtils.copy(bpmnInputStream,bpmn_stream);
//            pic_stream.close();
//            bpmn_stream.close();
//            picInputStieam.close();
//            bpmnInputStream.close();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  查询流程定义的历史信息
     * @date： 2022/3/30 22:12
     */
    @GetMapping("/getHistory")
    public void  getHitory(String InstanceId){
//       获取引擎
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
//        获取HistoryService
        HistoryService historyService = defaultProcessEngine.getHistoryService();
//       获取actinst表的查询对象
        HistoricActivityInstanceQuery activityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
//        根据InstanceId查询一个流程的所有信息
        HistoricActivityInstanceQuery query = activityInstanceQuery.processInstanceId(InstanceId)
//        排序等操作
                                                            .orderByHistoricActivityInstanceStartTime().asc();
        List<HistoricActivityInstance> historicActivityInstanceList = query.list();
        for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
            System.out.println(historicActivityInstance);
        }
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  流程定义的挂起和激活
     * @date： 2022/3/30 22:50
     */
    @GetMapping("/suspendOrActivAll")
    public void suspendOrActiv(String processKey){
//        获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        根据流程定义key查找流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(processKey).singleResult();
//        查看流程定义是否是挂起状态
        boolean suspended = processDefinition.isSuspended();
//        获取流程定义的Id
        String id = processDefinition.getId();
        if (suspended){
            repositoryService.activateProcessDefinitionById(id,true,null);
            System.out.println("流程定义ID:"+id+"已激活");
        }else {
            repositoryService.suspendProcessDefinitionById(id,true,null);
            System.out.println("流程定义ID:"+id+"已挂起");

        }
    }

    /**
     * @author： hj
     * @version： 1.0
     * @methodDes：  挂起单个流程实例
     * @date： 2022/3/30 23:02
     */
    @GetMapping("/suspendOrActivSingle")
    public void suspendOrActivSingle(String InstanceId){
//        获取引擎
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
//        获取RuntimeService
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
//        根据InstanceId查询流程实例信息
        ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(InstanceId).singleResult();
//        判断该流程是否被挂起
        boolean suspended = instance.isSuspended();
        String processInstanceId = instance.getId();
        if (suspended) {
            runtimeService.activateProcessInstanceById(processInstanceId);
            System.out.println("流程实例ID"+processInstanceId+"已经激活");
        }else {
            runtimeService.suspendProcessInstanceById(processInstanceId);
            System.out.println("流程实例ID"+processInstanceId+"已经挂起");
        }
    }





}
